﻿using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Collections.Generic;

namespace BYFW.Model.Authorization
{
    /// <summary>
    /// 用户类，权限的优先级：强制禁止->额外允许->角色定义的权限
    /// </summary>
    public class User : BOL.BaseConfigEntity
    {
        public User()
        {
            m_tableName = "auth_user";
            m_tblCacheManager.IsEnable = true;
            m_hasCode = true;
            m_hasName = true;
            m_hasComment = true;
        }


        protected string m_specialAllow = ",";
        protected string m_forceNotAllow = ",";

        protected List<int> m_roleIDs = null;
        protected List<KeyValuePair<int, int>> m_forceNotAllowMO = null;
        protected List<KeyValuePair<int, int>> m_specialAllowMO = null;

        /// <summary>
        /// 本用户的所有角色
        /// </summary>
        public List<int> RoleIDs
        {
            get
            {
                if (m_roleIDs == null)
                {
                    m_roleIDs = this.GetRoleIDs(m_id);
                }
                return m_roleIDs;
            }
        }
        /// <summary>
        /// 本用户被强制禁止的权限列表
        /// </summary>
        public List<KeyValuePair<int, int>> ForceNotAllowMO
        {
            get
            {
                if (m_forceNotAllowMO == null)
                {
                    m_forceNotAllowMO = this.GetMOListFromString(m_forceNotAllow);
                }
                return m_forceNotAllowMO;
            }
        }
        /// <summary>
        /// 本用户被额外允许的权限列表
        /// </summary>
        public List<KeyValuePair<int, int>> SpecialAllowMO
        {
            get
            {
                if (m_specialAllowMO == null)
                {
                    m_specialAllowMO = this.GetMOListFromString(m_specialAllow);
                }
                return m_specialAllowMO;
            }
        }

        public override void Init()
        {
            base.Init();
            m_roleIDs = null;
            m_forceNotAllowMO = null;
            m_specialAllowMO = null;
        }
        protected override void FillContainer()
        {
            base.FillContainer();
            this.m_container.Add("forceNotAllow", m_forceNotAllow);
            this.m_container.Add("specialAllow", m_specialAllow);
        }
        public override bool GetProperties(DataRow record)
        {
            if (!base.GetProperties(record))
            {
                return false;
            }
            m_forceNotAllow = this.GetStringValue(record, "forceNotAllow");
            m_specialAllow = this.GetStringValue(record, "specialAllow");
            return true;
        }

        /// <summary>
        /// 添加额外允许的权限
        /// </summary>
        /// <param name="mid">模块ID</param>
        /// <param name="oid">操作ID</param>
        public void AddSpecialMO(int mid, int oid)
        {
            this.AddMO(SpecialAllowMO, mid, oid);
            m_specialAllow = this.GetMOStringFromList(SpecialAllowMO);
        }
        /// <summary>
        /// 添加禁止权限
        /// </summary>
        /// <param name="mid">模块ID</param>
        /// <param name="oid">操作ID</param>
        public void AddNotAllowMO(int mid, int oid)
        {
            this.AddMO(ForceNotAllowMO, mid, oid);
            m_forceNotAllow = this.GetMOStringFromList(ForceNotAllowMO);
        }
        /// <summary>
        /// 移除额外允许的权限
        /// </summary>
        /// <param name="mid">模块ID</param>
        /// <param name="oid">操作ID</param>
        public void RemoveSpecialMO(int mid, int oid)
        {
            this.RemoveMO(SpecialAllowMO, mid, oid);
            m_specialAllow = this.GetMOStringFromList(SpecialAllowMO);
        }
        /// <summary>
        /// 移除禁止的权限
        /// </summary>
        /// <param name="mid">模块ID</param>
        /// <param name="oid">操作ID</param>
        public void RemoveNotAllowMO(int mid, int oid)
        {
            this.RemoveMO(ForceNotAllowMO, mid, oid);
            m_forceNotAllow = this.GetMOStringFromList(ForceNotAllowMO);
        }
        /// <summary>
        /// 当前用户是否具有指定模块指定操作的权限
        /// </summary>
        /// <param name="mid">模块ID</param>
        /// <param name="oid">操作ID</param>
        /// <returns></returns>
        public bool HavePermission(int mid, int oid)
        {
            if (FindMO(ForceNotAllowMO, mid, oid) > -1)
            {
                return false;
            }
            if (FindMO(SpecialAllowMO, mid, oid) > -1)
            {
                return true;
            }
            List<int> roleIDs = new List<int>();
            for (int i = 0; i < RoleIDs.Count; i++)
            {
                roleIDs.Add(RoleIDs[i]);
            }
            return new MRORelation().IsAllowed(mid, oid, roleIDs);
        }
        /// <summary>
        /// 当前用户是否具有指定模块指定操作的权限
        /// </summary>
        /// <param name="mcode">模块代码</param>
        /// <param name="ocode">操作代码</param>
        /// <returns></returns>
        public bool HavePermission(string mcode, string ocode)
        {
            Module m = new Module();
            m.GetProperties(mcode);
            Operation o = new Operation();
            o.GetProperties(ocode);
            return HavePermission(m.ID, o.ID);
        }


        /// <summary>
        /// 将权限字符串描述转换为列表【去除了重复项】
        /// </summary>
        /// <param name="MOString">模块－操作转换为列表形式</param>
        /// <returns></returns>
        protected List<KeyValuePair<int, int>> GetMOListFromString(string MOString)
        {
            List<KeyValuePair<int, int>> res = new List<KeyValuePair<int, int>>();
            string[] list = MOString.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
            for (int i = 0; i < list.Length; i++)
            {
                int moid = 0;
                int opid = 0;
                string[] tmp = list[i].Split("-".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                if (tmp.Length == 2)
                {
                    int.TryParse(tmp[0], out moid);
                    int.TryParse(tmp[1], out opid);
                }
                if (moid == 0 || opid == 0)
                {
                    continue;
                }
                res.Add(new KeyValuePair<int, int>(moid, opid));
            }
            return this.RemoveRepeatMO(res);
        }
        /// <summary>
        /// 由列表获取权限字符串描述
        /// </summary>
        /// <param name="list">列表形式的模块－操作</param>
        /// <returns></returns>
        protected string GetMOStringFromList(List<KeyValuePair<int, int>> list)
        {
            string res = ",";
            for (int i = 0; i < list.Count; i++)
            {
                res += list[i].Key + "-" + list[i].Value + ",";
            }
            return res;
        }
        /// <summary>
        /// 添加用户对某模块的操作【允许或禁止】到指定的列表
        /// </summary>
        /// <param name="moduleID"></param>
        /// <param name="operationID"></param>
        protected void AddMO(List<KeyValuePair<int, int>> list, int moduleID, int operationID)
        {
            if (FindMO(list, moduleID, operationID) == -1)
            {
                list.Add(new KeyValuePair<int, int>(moduleID, operationID));
            }
        }
        /// <summary>
        /// 从指定的列表移除用户对某模块的操作【允许或禁止】【重复也一并移除】
        /// </summary>
        /// <param name="moduleID"></param>
        /// <param name="operationID"></param>
        protected void RemoveMO(List<KeyValuePair<int, int>> list, int moduleID, int operationID)
        {
            for (int i = 0; i < list.Count; i++)
            {
                if (moduleID == list[i].Key && operationID == list[i].Value)
                {
                    list.RemoveAt(i);
                    i--;
                }
            }
        }
        /// <summary>
        /// 在指定的列表中返回第一个指定的模块－操作
        /// </summary>
        /// <param name="list"></param>
        /// <param name="moduleID"></param>
        /// <param name="operationID"></param>
        /// <returns></returns>
        protected int FindMO(List<KeyValuePair<int, int>> list, int moduleID, int operationID)
        {
            int index = -1;
            for (int i = 0; i < list.Count; i++)
            {
                if (moduleID == list[i].Key && operationID == list[i].Value)
                {
                    index = i;
                    break;
                }
            }
            return index;
        }
        /// <summary>
        /// 移除重复模块－操作项
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        public List<KeyValuePair<int, int>> RemoveRepeatMO(List<KeyValuePair<int, int>> list)
        {
            List<KeyValuePair<int, int>> res = new List<KeyValuePair<int,int>>();
            for(int i=0;i<list.Count;i++)
            {
                if (FindMO(res, list[i].Key, list[i].Value) > -1)
                {
                    res.Add(list[i]);
                }
            }
            return res;
        }

        /// <summary>
        /// 获取本用户对应的角色ID列表
        /// </summary>
        /// <returns></returns>
        public List<int> GetRoleIDs(int userID)
        {
            List<int> res = new List<int>();
            List<RURelation> urs = new RURelation().GetListByUID(userID);
            for (int i = 0; i < urs.Count; i++)
            {
                bool find = false;
                for (int j = 0; j < res.Count; j++)
                {
                    if (urs[i].RoleID == res[j])
                    {
                        find = true;
                        break;
                    }
                }
                if (!find)
                {
                    res.Add(urs[i].RoleID);
                }
            }
            return res;
        }

        /// <summary>
        /// 获取具有指定操作的多个用户
        /// </summary>
        /// <param name="mid"></param>
        /// <param name="oid"></param>
        /// <returns></returns>
        public DataTable GetRecordsByMO(int mid, int oid)
        {
            string cond = " WHERE {0} NOT LIKE '%{3}%' AND ({1} LIKE '%{3}%' OR {2} IN ({4}))";
            DataTable dt = new MRORelation().GetRecords(mid, oid, null);
            List<int> rids = new List<int>();
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                MRORelation tmp = new MRORelation();
                tmp.GetProperties(dt.Rows[i]);
                rids.Add(tmp.RoleID);
            }
            DataTable dt1 = new RURelation().GetRecords(rids);
            string uids = "";
            for (int i = 0; i < dt1.Rows.Count; i++)
            {
                RURelation tmp = new RURelation();
                tmp.GetProperties(dt.Rows[i]);
                uids += DB.GetVal(tmp.UserID) + ",";
            }
            uids = uids.TrimEnd(',').Trim();
            if (uids == "")
            {
                uids = DB.GetVal(0);
            }
            cond = string.Format(cond, DB.GetCol("forceNotAllow"), DB.GetCol("specialAllow"), DB.GetCol("id"), DB.GetVal("," + mid + "-" + oid + ","), uids);
            return this.GetRecords(cond);
        }
        /// <summary>
        /// 获取指定用户的所有角色对应的操作
        /// </summary>
        /// <returns></returns>
        public List<KeyValuePair<int, int>> GetRolesMO(int userID)
        {
            List<KeyValuePair<int, int>> res = new List<KeyValuePair<int, int>>();
            DataTable dt = new MRORelation().GetRecords(null, null, this.GetRoleIDs(userID));
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                MRORelation tmp = new MRORelation();
                tmp.GetProperties(dt.Rows[i]);
                res.Add(new KeyValuePair<int, int>(tmp.ModuleID, tmp.OperationID));
            }
            return this.RemoveRepeatMO(res);
        }

        new protected void  Test()
        {
            DataTable dt = new DataTable();
            DataColumn dc1 = new DataColumn("col1");
            DataColumn dc2 = new DataColumn("col2");
            dt.Columns.Add(dc1);
            dt.Columns.Add(dc2);
            DataRow dr1 = dt.NewRow();
            dr1[0] = "col1";
            dr1[1] = "nihao";
            dt.Rows.Add(dr1);
            DataRow dr2 = dt.NewRow();
            dr2[0] = "col2";
            dr2[1] = "hello";
            dt.Rows.Add(dr2);
            DataRow[] drs = dt.Select("col1 not like '%3%' and (col2 like '%3%' or  col2 in ('nih1ao','hello'))");
            Console.WriteLine(drs.Length);
        }
    }
}
